package bangry.chat.server.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;

import bangry.chat.server.control.ChatServer;
import bangry.chat.util.server.util.GUIUtil;

// 싱글톤(Singleton) 패턴 적용 클래스
public class ServerMonitor extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JLabel portL = null;
	private JTextField portTF = null;
	private JPanel monitorPanel = null;
	private JScrollPane clientListSP = null;
	private JList clientList = null;
	private JButton startB = null;
	private JButton stopB = null;
	private JScrollPane monitorSP = null;
	private JTextArea monitorTA = null;
	private JLabel logL1 = null;
	private JLabel logoL2 = null;
	private JLabel logoL3 = null;
	private JLabel logoL4 = null;
	private JLabel logoL5 = null;
	private JLabel runningL = null;
	private JLabel stopL = null;
	private JLabel portImageL = null;

	private DefaultListModel clientListModel;

	static ServerMonitor instance;

	ChatServer chatServer;
	int port;

	// 싱글톤 패턴 적용을 위해 생성자를 private 로 선언
	private ServerMonitor() {
		initialize();
		setDefaultEnable();
	}

	// 클래스 메소드 정의
	public static ServerMonitor getInstance() {
		if (instance == null) {
			instance = new ServerMonitor();
		}
		return instance;
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(983, 795);
		this.setContentPane(getJContentPane());
		this.setTitle(":: 방그리 채팅 서버 ::");
		this.addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowClosing(java.awt.event.WindowEvent e) {
				exit();
			}
		});
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			portImageL = new JLabel();
			portImageL.setBounds(new Rectangle(823, 9, 97, 93));
			portImageL.setIcon(new ImageIcon(getClass().getResource(
					"/images/icons6976.png")));
			portImageL.setText("");
			logoL5 = new JLabel();
			logoL5.setBounds(new Rectangle(652, 10, 125, 122));
			logoL5.setIcon(new ImageIcon(getClass().getResource(
					"/images/icons8581.png")));
			logoL5.setText("");
			logoL4 = new JLabel();
			logoL4.setBounds(new Rectangle(494, 9, 125, 122));
			logoL4.setIcon(new ImageIcon(getClass().getResource(
					"/images/icons8583.png")));
			logoL4.setText("");
			logoL3 = new JLabel();
			logoL3.setBounds(new Rectangle(336, 9, 125, 122));
			logoL3.setIcon(new ImageIcon(getClass().getResource(
					"/images/icons8578.png")));
			logoL3.setText("");
			logoL2 = new JLabel();
			logoL2.setBounds(new Rectangle(176, 9, 125, 122));
			logoL2.setIcon(new ImageIcon(getClass().getResource(
					"/images/icons8576.png")));
			logoL2.setText("");
			logL1 = new JLabel();
			logL1.setBounds(new Rectangle(16, 9, 125, 122));
			logL1.setIcon(new ImageIcon(getClass().getResource(
					"/images/icons8564.png")));
			logL1.setText("");

			runningL = new JLabel();
			runningL.setBounds(new Rectangle(16, 710, 40, 40));
			runningL.setIcon(new ImageIcon(getClass().getResource(
					"/images/start.gif")));
			runningL.setText("");

			portL = new JLabel();
			portL.setBounds(new Rectangle(787, 107, 67, 24));
			portL.setBorder(BorderFactory.createLineBorder(Color.gray, 1));
			portL.setHorizontalAlignment(SwingConstants.CENTER);
			portL.setText("서버포트");
			jContentPane = new JPanel();
			jContentPane.setLayout(null);
			jContentPane.add(portL, null);
			jContentPane.add(getPortTF(), null);
			jContentPane.add(getMonitorPanel(), null);
			jContentPane.add(getClientListSP(), null);
			jContentPane.add(getStartB(), null);
			jContentPane.add(getStopB(), null);
			jContentPane.add(logL1, null);
			jContentPane.add(logoL2, null);
			jContentPane.add(logoL3, null);
			jContentPane.add(logoL4, null);
			jContentPane.add(logoL5, null);
			jContentPane.add(portImageL, null);
			jContentPane.add(runningL, null);

			logL1.addMouseListener(new MouseAdapter() {
				// 커서변경
				public void mouseEntered(MouseEvent e) {
					logL1.setCursor(Cursor
							.getPredefinedCursor(Cursor.HAND_CURSOR));
				}

				public void mouseClicked(MouseEvent e) {
					try {
						UIManager
								.setLookAndFeel("org.jvnet.substance.skin.SubstanceMagmaLookAndFeel");
						SwingUtilities.updateComponentTreeUI(getContentPane());
					} catch (Exception ex) {
					}
				}
			});
			logoL2.addMouseListener(new MouseAdapter() {
				public void mouseEntered(MouseEvent e) {
					logoL2.setCursor(Cursor
							.getPredefinedCursor(Cursor.HAND_CURSOR));
				}

				public void mouseClicked(MouseEvent e) {
					try {
						UIManager
								.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
						SwingUtilities.updateComponentTreeUI(getContentPane());
					} catch (Exception ex) {
					}
				}
			});
			logoL2.addMouseListener(new MouseAdapter() {
				public void mouseEntered(MouseEvent e) {
					logoL2.setCursor(Cursor
							.getPredefinedCursor(Cursor.HAND_CURSOR));
				}

				public void mouseClicked(MouseEvent e) {
					try {
						UIManager
								.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
						SwingUtilities.updateComponentTreeUI(getContentPane());
					} catch (Exception ex) {
					}
				}
			});
			logoL3.addMouseListener(new MouseAdapter() {
				public void mouseEntered(MouseEvent e) {
					logoL3.setCursor(Cursor
							.getPredefinedCursor(Cursor.HAND_CURSOR));
				}

				public void mouseClicked(MouseEvent e) {
					try {
						Runtime
								.getRuntime()
								.exec("C:/Program Files/Internet Explorer/IEXPLORE.EXE http://www.hanbitedu.co.kr");
					} catch (IOException e1) {
					}

				}
			});
		}
		return jContentPane;
	}

	// 초기화면 활성화/비활성화 설정
	public void setDefaultEnable() {
		portTF.requestFocus();
		portTF.setEditable(true);

		monitorTA.setText("⊙⊙⊙ 채팅 서버가 중지 상태입니다 ⊙⊙⊙");
		monitorTA.setEnabled(false);
		monitorTA.setEditable(false);

		clientListModel.removeAllElements();

		runningL.setIcon(new ImageIcon(getClass().getResource(
				"/images/stop.gif")));
		runningL.setEnabled(false);

		runningL
				.setToolTipText("<HTML><font face='굴림' color='red' size='3'>채팅서버가 중지 상태입니다.</font></HTML>");
		startB.setEnabled(true);
		stopB.setEnabled(false);

	}

	// 채팅서버 구동시 활성화/비활성화 설정
	public void setComponentEnable() {
		portTF.setEditable(false);

		monitorTA.setEnabled(true);
		monitorTA.setText("");

		runningL.setEnabled(true);
		runningL.setIcon(new ImageIcon(getClass().getResource(
				"/images/start.gif")));
		runningL
				.setToolTipText("<HTML><font face='굴림' color='yellow' size='3'>채팅서버가 정상적으로 구동중입니다</font></HTML>");

		startB.setEnabled(false);
		stopB.setEnabled(true);

	}

	/**
	 * This method initializes portTF
	 * 
	 * @return javax.swing.JTextField
	 */
	private JTextField getPortTF() {
		if (portTF == null) {
			portTF = new JTextField("7777");
			portTF.setBounds(new Rectangle(859, 107, 97, 24));
			portTF.setBorder(BorderFactory.createLineBorder(Color.gray, 1));
		}
		return portTF;
	}

	/**
	 * This method initializes monitorPanel
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getMonitorPanel() {
		if (monitorPanel == null) {
			monitorPanel = new JPanel();
			monitorPanel.setLayout(new BorderLayout());
			monitorPanel.setBounds(new Rectangle(15, 141, 764, 565));
			monitorPanel
					.setBorder(BorderFactory
							.createTitledBorder(
									null,
									"\uc811\uc18d \ud074\ub77c\uc774\uc5b8\ud2b8 \ubaa8\ub2c8\ud130",
									TitledBorder.DEFAULT_JUSTIFICATION,
									TitledBorder.DEFAULT_POSITION, new Font(
											"Dialog", Font.PLAIN, 14),
									new Color(255, 255, 255)));
			monitorPanel.add(getMonitorSP(), BorderLayout.CENTER);
		}
		return monitorPanel;
	}

	/**
	 * This method initializes clientListSP
	 * 
	 * @return javax.swing.JScrollPane
	 */
	private JScrollPane getClientListSP() {
		if (clientListSP == null) {
			clientListSP = new JScrollPane();
			clientListSP.setBounds(new Rectangle(783, 141, 177, 565));
			clientListSP.setBorder(BorderFactory.createTitledBorder(null,
					"\uc811\uc18d\uc790 \ub9ac\uc2a4\ud2b8",
					TitledBorder.DEFAULT_JUSTIFICATION,
					TitledBorder.DEFAULT_POSITION, new Font("Dialog",
							Font.PLAIN, 14), new Color(255, 255, 255)));
			clientListSP.setViewportView(getClientList());
		}
		return clientListSP;
	}

	/**
	 * This method initializes clientList
	 * 
	 * @return javax.swing.JList
	 */

	private JList getClientList() {
		if (clientList == null) {
			clientList = new JList();
			clientListModel = new DefaultListModel();
			clientList.setModel(clientListModel);
		}
		return clientList;
	}

	/**
	 * This method initializes startB
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getStartB() {
		if (startB == null) {
			startB = new JButton();
			startB.setBounds(new Rectangle(750, 717, 100, 35));
			startB.setText("서버구동");
			startB.setOpaque(false);
			startB.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					// 클라이언트의 연결을 수신하는 역할의 객체 생성
					if (getPortTF().getText() != null
							&& getPortTF().getText().trim().length() != 0) {
						port = Integer.parseInt(getPortTF().getText());
						chatServer = new ChatServer(port);
						chatServer.start();
						setComponentEnable();
					}
				}
			});
		}
		return startB;
	}

	/**
	 * This method initializes stopB
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getStopB() {
		if (stopB == null) {
			stopB = new JButton();
			stopB.setBounds(new Rectangle(855, 717, 100, 35));
			stopB.setText("서버종료");
			stopB.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					// 서버스레드 종료
					chatServer.serverStop();
					setDefaultEnable();

				}
			});
		}
		return stopB;
	}

	/**
	 * This method initializes monitorSP
	 * 
	 * @return javax.swing.JScrollPane
	 */
	private JScrollPane getMonitorSP() {
		if (monitorSP == null) {
			monitorSP = new JScrollPane();
			monitorSP
					.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
			monitorSP
					.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
			monitorSP.setViewportView(getMonitorTA());
		}
		return monitorSP;
	}

	/**
	 * This method initializes monitorTA
	 * 
	 * @return javax.swing.JTextArea
	 */
	private JTextArea getMonitorTA() {
		if (monitorTA == null) {
			monitorTA = new JTextArea();
			monitorTA.setFont(new Font("Dialog", Font.BOLD, 18));
			// monitorTA.setForeground(Color.yellow);
		}
		return monitorTA;
	}

	private void exit() {
		// 서버가 실행중이지 않으면 정상 종료
		if (!stopB.isEnabled()) {
			JOptionPane.showMessageDialog(null, "프로그램을 정상 종료합니다.", "알림",
					JOptionPane.INFORMATION_MESSAGE);
			setVisible(false);
			dispose();
			System.exit(0);
		} else {
			// 서버 실행중엔 종료 불가능
			JOptionPane.showMessageDialog(null, "서버실행중엔 프로그램을 종료할 수 없습니다.",
					"알림", JOptionPane.INFORMATION_MESSAGE);
		}

	}
	

	// 모니터창에 메시지 출력
	public void appendMessage(String message) {
		monitorTA.append(message + "\n");
		int length = monitorTA.getText().length();
		monitorTA.setCaretPosition(length);
	}

	// 클라이언트 리스트에 추가
	public void addClientList(String userInfo) {
		clientListModel.addElement(userInfo);
	}

	// 클라이언트 리스트에서 제거
	public void removeClientList(String clientIP, String clientID) {
		clientListModel.removeElement(clientID + " [" + clientIP + "]");
	}

}
